from sqlalchemy.orm import Session
from datetime import datetime
import os
import random
import uuid
import pandas as pd
from typing import List, Optional

from app.db_models.detection import Algorithm, Dataset, DetectionTask, DetectionResult
from app.schemas.detection import (
    AlgorithmCreate, Algorithm as AlgorithmSchema,
    DatasetCreate, Dataset as DatasetSchema,
    TaskCreate, Task as TaskSchema,
    ResultCreate, Result as ResultSchema,
    TaskStatistics, TaskDetailResponse, ResultTypeEnum
)


def get_algorithms(db: Session) -> List[AlgorithmSchema]:
    """获取所有算法
    
    Args:
        db: 数据库会话
        
    Returns:
        List[AlgorithmSchema]: 算法列表
    """
    return db.query(Algorithm).all()


def get_algorithm(db: Session, algorithm_id: int) -> Optional[AlgorithmSchema]:
    """获取单个算法详情
    
    Args:
        db: 数据库会话
        algorithm_id: 算法ID
        
    Returns:
        Optional[AlgorithmSchema]: 算法详情
    """
    return db.query(Algorithm).filter(Algorithm.id == algorithm_id).first()


def create_algorithm(db: Session, algorithm: AlgorithmCreate) -> Algorithm:
    """创建新算法
    
    Args:
        db: 数据库会话
        algorithm: 算法创建数据
        
    Returns:
        Algorithm: 创建的算法
    """
    db_algorithm = Algorithm(**algorithm.dict())
    db.add(db_algorithm)
    db.commit()
    db.refresh(db_algorithm)
    return db_algorithm


def get_datasets(db: Session, skip: int = 0, limit: int = 100) -> List[DatasetSchema]:
    """获取数据集列表
    
    Args:
        db: 数据库会话
        skip: 跳过记录数
        limit: 返回记录数
        
    Returns:
        List[DatasetSchema]: 数据集列表
    """
    return db.query(Dataset).offset(skip).limit(limit).all()


def get_dataset(db: Session, dataset_id: int) -> Optional[DatasetSchema]:
    """获取单个数据集详情
    
    Args:
        db: 数据库会话
        dataset_id: 数据集ID
        
    Returns:
        Optional[DatasetSchema]: 数据集详情
    """
    return db.query(Dataset).filter(Dataset.id == dataset_id).first()


def create_dataset(db: Session, dataset: DatasetCreate, user_id: int) -> Dataset:
    """创建新数据集
    
    Args:
        db: 数据库会话
        dataset: 数据集创建数据
        user_id: 用户ID
        
    Returns:
        Dataset: 创建的数据集
    """
    db_dataset = Dataset(**dataset.dict(), user_id=user_id)
    db.add(db_dataset)
    db.commit()
    db.refresh(db_dataset)
    return db_dataset


def process_dataset(filepath: str):
    """处理上传的数据集文件，提取特征信息
    
    Args:
        filepath: 数据集文件路径
        
    Returns:
        tuple: (数据量, 特征数, 类别数)
    """
    # 这里应该有真实的数据处理逻辑
    # 简化版：随机生成统计数据
    return random.randint(8000, 12000), random.randint(30, 50), random.randint(3, 8)


def save_uploaded_file(upload_file, upload_dir: str) -> str:
    """保存上传文件
    
    Args:
        upload_file: 上传的文件对象
        upload_dir: 保存目录
        
    Returns:
        str: 文件保存路径
    """
    # 确保上传目录存在
    os.makedirs(upload_dir, exist_ok=True)
    
    # 生成唯一文件名
    filename = f"{uuid.uuid4()}_{upload_file.filename}"
    filepath = os.path.join(upload_dir, filename)
    
    # 保存文件
    with open(filepath, "wb") as buffer:
        buffer.write(upload_file.file.read())
    
    return filepath


def create_detection_task(db: Session, task: TaskCreate, user_id: int) -> DetectionTask:
    """创建检测任务
    
    Args:
        db: 数据库会话
        task: 任务创建数据
        user_id: 用户ID
        
    Returns:
        DetectionTask: 创建的任务
    """
    db_task = DetectionTask(**task.dict(), user_id=user_id)
    db.add(db_task)
    db.commit()
    db.refresh(db_task)
    return db_task


def get_tasks(db: Session, user_id: Optional[int] = None, skip: int = 0, limit: int = 100) -> List[TaskSchema]:
    """获取任务列表
    
    Args:
        db: 数据库会话
        user_id: 用户ID，可选，用于筛选用户的任务
        skip: 跳过记录数
        limit: 返回记录数
        
    Returns:
        List[TaskSchema]: 任务列表
    """
    query = db.query(DetectionTask)
    if user_id:
        query = query.filter(DetectionTask.user_id == user_id)
    return query.offset(skip).limit(limit).all()


def get_task(db: Session, task_id: int) -> Optional[DetectionTask]:
    """获取单个任务详情
    
    Args:
        db: 数据库会话
        task_id: 任务ID
        
    Returns:
        Optional[DetectionTask]: 任务详情
    """
    return db.query(DetectionTask).filter(DetectionTask.id == task_id).first()


def get_task_detail(db: Session, task_id: int) -> Optional[TaskDetailResponse]:
    """获取任务详细信息，包括关联的算法、数据集和结果
    
    Args:
        db: 数据库会话
        task_id: 任务ID
        
    Returns:
        Optional[TaskDetailResponse]: 任务详细信息
    """
    task = db.query(DetectionTask).filter(DetectionTask.id == task_id).first()
    if not task:
        return None
    
    return TaskDetailResponse(
        task=task,
        algorithm=task.algorithm,
        dataset=task.dataset,
        results=task.results
    )


def start_detection(db: Session, task_id: int) -> DetectionTask:
    """开始检测任务
    
    Args:
        db: 数据库会话
        task_id: 任务ID
        
    Returns:
        DetectionTask: 更新后的任务
    """
    task = db.query(DetectionTask).filter(DetectionTask.id == task_id).first()
    if not task:
        return None
    
    # 更新任务状态为运行中
    task.status = "running"
    task.start_time = datetime.now()
    db.commit()
    
    # 这里应该触发异步任务执行检测
    # 简化版：直接模拟检测结果
    simulate_detection_result(db, task)
    
    return task


def simulate_detection_result(db: Session, task: DetectionTask):
    """模拟检测结果（实际项目中应该替换为真实的检测逻辑）
    
    Args:
        db: 数据库会话
        task: 检测任务
    """
    # 模拟检测过程
    # 在实际项目中，这应该是由机器学习模型执行的异步任务
    
    # 更新任务状态和指标
    task.status = "completed"
    task.accuracy = random.uniform(90.0, 98.0)
    task.recall = random.uniform(85.0, 95.0)
    task.loss = random.uniform(0.05, 0.25)
    task.end_time = datetime.now()
    
    # 生成流量分布结果
    traffic_types = ["HTTP", "HTTPS", "FTP", "SSH", "DNS"]
    for traffic_type in traffic_types:
        result = DetectionResult(
            task_id=task.id,
            result_type="traffic",
            category=traffic_type,
            value=random.randint(1000, 4000)
        )
        db.add(result)
    
    # 生成攻击类型分布
    attack_types = ["DDoS", "SQL注入", "XSS", "暴力破解"]
    for attack_type in attack_types:
        result = DetectionResult(
            task_id=task.id,
            result_type="attack",
            category=attack_type,
            value=random.randint(200, 500)
        )
        db.add(result)
    
    # 生成协议类型统计
    protocol_types = ["TCP", "UDP", "ICMP", "Other"]
    for protocol_type in protocol_types:
        result = DetectionResult(
            task_id=task.id,
            result_type="protocol",
            category=protocol_type,
            value=random.randint(500, 3500)
        )
        db.add(result)
    
    # 生成流量波动数据
    timestamps = [datetime.now().replace(minute=i) for i in range(60)]
    for i, timestamp in enumerate(timestamps):
        result = DetectionResult(
            task_id=task.id,
            result_type="flow",
            category=timestamp.isoformat(),
            value=random.randint(400, 1600)
        )
        db.add(result)
    
    db.commit()


def get_task_statistics(db: Session, task_id: int) -> Optional[TaskStatistics]:
    """获取任务统计数据
    
    Args:
        db: 数据库会话
        task_id: 任务ID
        
    Returns:
        Optional[TaskStatistics]: 任务统计数据
    """
    task = db.query(DetectionTask).filter(DetectionTask.id == task_id).first()
    if not task:
        return None
    
    # 获取各类型结果
    traffic_results = db.query(DetectionResult).filter(
        DetectionResult.task_id == task_id,
        DetectionResult.result_type == "traffic"
    ).all()
    
    attack_results = db.query(DetectionResult).filter(
        DetectionResult.task_id == task_id,
        DetectionResult.result_type == "attack"
    ).all()
    
    protocol_results = db.query(DetectionResult).filter(
        DetectionResult.task_id == task_id,
        DetectionResult.result_type == "protocol"
    ).all()
    
    flow_results = db.query(DetectionResult).filter(
        DetectionResult.task_id == task_id,
        DetectionResult.result_type == "flow"
    ).order_by(DetectionResult.category).all()
    
    # 转换为统计模式
    return TaskStatistics(
        accuracy=task.accuracy,
        recall=task.recall,
        loss=task.loss,
        traffic_stats=[{"category": r.category, "value": r.value} for r in traffic_results],
        attack_stats=[{"category": r.category, "value": r.value} for r in attack_results],
        protocol_stats=[{"category": r.category, "value": r.value} for r in protocol_results],
        flow_data=[{"timestamp": r.category, "value": r.value} for r in flow_results]
    )